agentmux_srv\backend\reactive/
poller.rs1use std::collections::HashMap;
6use std::sync::{Mutex, RwLock};
7
8use super::handler::ReactiveHandler;
9use super::types::{PollerConfig, PollerStatus};
10use super::now_unix_millis;
11
12pub struct Poller {
14 config: RwLock<PollerConfig>,
15 _handler: &'static ReactiveHandler,
16 running: Mutex<bool>,
17 poll_count: Mutex<u64>,
18 injections_count: Mutex<u64>,
19 last_poll: Mutex<Option<u64>>,
20 last_error: Mutex<Option<String>>,
21}
22
23impl Poller {
24 pub fn new(config: PollerConfig, handler: &'static ReactiveHandler) -> Self {
26 Self {
27 config: RwLock::new(config),
28 _handler: handler,
29 running: Mutex::new(false),
30 poll_count: Mutex::new(0),
31 injections_count: Mutex::new(0),
32 last_poll: Mutex::new(None),
33 last_error: Mutex::new(None),
34 }
35 }
36
37 #[allow(dead_code)]
39 pub fn is_configured(&self) -> bool {
40 let config = self.config.read().unwrap();
41 config.agentmux_url.is_some() && config.agentmux_token.is_some()
42 }
43
44 pub fn is_running(&self) -> bool {
46 *self.running.lock().unwrap()
47 }
48
49 pub fn stats(&self) -> HashMap<String, serde_json::Value> {
51 let mut m = HashMap::new();
52 m.insert(
53 "poll_count".to_string(),
54 serde_json::json!(*self.poll_count.lock().unwrap()),
55 );
56 m.insert(
57 "injections_count".to_string(),
58 serde_json::json!(*self.injections_count.lock().unwrap()),
59 );
60 m.insert(
61 "last_poll".to_string(),
62 serde_json::json!(*self.last_poll.lock().unwrap()),
63 );
64 m.insert(
65 "last_error".to_string(),
66 serde_json::json!(*self.last_error.lock().unwrap()),
67 );
68 m
69 }
70
71 pub fn status(&self) -> PollerStatus {
73 let config = self.config.read().unwrap();
74 PollerStatus {
75 configured: config.agentmux_url.is_some() && config.agentmux_token.is_some(),
76 running: self.is_running(),
77 url: config.agentmux_url.clone(),
78 has_token: config.agentmux_token.is_some(),
79 poll_count: *self.poll_count.lock().unwrap(),
80 injections_count: *self.injections_count.lock().unwrap(),
81 last_poll: *self.last_poll.lock().unwrap(),
82 }
83 }
84
85 pub fn reconfigure(&self, url: Option<String>, token: Option<String>) {
87 let mut config = self.config.write().unwrap();
88 config.agentmux_url = url;
89 config.agentmux_token = token;
90 }
91
92 #[allow(dead_code)]
94 pub fn record_poll(&self) {
95 *self.poll_count.lock().unwrap() += 1;
96 *self.last_poll.lock().unwrap() = Some(now_unix_millis());
97 *self.last_error.lock().unwrap() = None;
98 }
99
100 #[allow(dead_code)]
102 pub fn record_error(&self, err: &str) {
103 *self.last_error.lock().unwrap() = Some(err.to_string());
104 }
105
106 #[allow(dead_code)]
108 pub fn record_injections(&self, count: u64) {
109 *self.injections_count.lock().unwrap() += count;
110 }
111
112 #[allow(dead_code)]
114 pub fn set_running(&self, running: bool) {
115 *self.running.lock().unwrap() = running;
116 }
117}